package Game;
import java.util.LinkedList;
import java.util.List;
import Conf.Consts;
import DB.DBUserConnector;
import Entities.User;
import Exceptions.GameCenterException;
import Exceptions.GameCenterException.GameCenterExceptionType;
import Exceptions.StrategoException;
import Logic.IPlayEngine;
import Server.EngineFactory;

/**
 * GameCenter class is responsible for holding all current games
 * while allowing to create new games or join existing games before they start.
 * it also holds the SCOREBOARD
 */
public class GameCenter implements IGameCenter  {
	
	private List<IGameInfo> GamesList =  new LinkedList<IGameInfo>();
	
	// The ID for the next PlayEngine we'll create. increases after the PlayEngine is created
	private int EngineID = 1;
	
	/*
	 * CreateNewGame  : Create New Game ("Room").
	 * throw GameException if MaxNumOfPlayers is <2 || >4.
	 * returns PlayEngine for the new game
	 */
	@Override
	public IPlayEngine CreateNewGame(String GameName,int GameMaxNumOfPlayers,int NumOfAiPlayers,String PlayerName) throws StrategoException {
		if (NumOfAiPlayers!=GameMaxNumOfPlayers-1)
			throw new GameCenterException(GameCenterExceptionType.InvalidNumberOfAIs);
		int curEngineId = EngineID++;
		EngineFactory factory = EngineFactory.getInstance();
		IPlayEngine _Engine = factory.getEngine(curEngineId);
		_Engine.setBoard(Consts.N, Consts.N);
		_Engine.setNumberOfPlayers(GameMaxNumOfPlayers);
		
		IGameInfo NewGame = new GameInfo(GameName,GameMaxNumOfPlayers,NumOfAiPlayers,curEngineId);
		for (int i=0;i<NumOfAiPlayers;i++) { 
			 _Engine.setPlayerName(i+1, "Computer" + (i+1));
			 _Engine.setAIPlayer(i+1);
			 _Engine.SetMySoldiersRandomlly(i+1);
		}
		int PlayerNumber = NewGame.AddPlayer(PlayerName);
		_Engine.setPlayerName(PlayerNumber, PlayerName);
		_Engine.setHumanPlayer(PlayerNumber);
		
		GamesList.add(NewGame);
		return _Engine;
	}
	
	// Returns the GameInfo for a specific game name
	 
	@Override
	public IGameInfo getGameInfo(String GameName)throws StrategoException{
		if (GamesList.size()==0)
			throw new GameCenterException(GameCenterExceptionType.NoAvaliableGames);
		else {
			for(int i=0; i<GamesList.size();i++){
				if (GamesList.get(i).getName().equals(GameName)) {
					return GamesList.get(i);
				}
			}
			throw new GameCenterException(GameCenterExceptionType.NoSuchGame);
		}
	}

	@Override
	public User signup(String username, String password) throws GameCenterException {
		if (username == null || password == null ||
				username.isEmpty() || password.isEmpty()) {
			throw new GameCenterException(GameCenterExceptionType.MissingSignupInformation);
		}

		if (getUser(username) != null) throw new GameCenterException(GameCenterExceptionType.UsernameTaken);
		
		User user = new User(username, password);
		DBUserConnector.addUser(user);
		return user;
	}

	@Override
	public User login(String username, String password) throws GameCenterException {
		User user = getUser(username);
		if (user == null) throw new GameCenterException(GameCenterExceptionType.NoSuchUser);
		if (!user.getPassword().equals(password)) throw new GameCenterException(GameCenterExceptionType.WrongPassword);
		
		return user;
	}

	@Override
	public User getUser(String username) {
		User user=DBUserConnector.getUser(username);
		return user;
	}

	@Override
	public void deleteUser(String username, String password)
			throws GameCenterException {
		login(username, password);
		DBUserConnector.deleteUser(username);
	}
}